package com.mycompany.myapp.aop.logging.aop.test;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * Create by wys on 2018/8/1
 *
 * aop使用
 * 5种类型的通知
 * before 前置通知
 *
 * around 通知包裹了被通知的方法，在被通知的方法调用之前和
 * 调用之后执行自定义的行为
 *
 */
@Aspect
@Component
public class AopTestOne {

    /**
     * 第一个*返回值的类型任意   第二个*类名
     * 第三个*方法名，括号表示参数
      */
  //  @Pointcut("execution(* com.mycompany.myapp.web.rest.aoptestcontroller..*.*(..))")
    @Pointcut("execution(* com.mycompany.myapp.web.rest.aoptestcontroller..AOPTestOneController.*(..))")
    public void executeService() {

    }

    @Before("executeService()")
    public void deBefore(JoinPoint joinPoint) {
        System.out.println("--aop=before");
        System.out.println("=[one");


        Signature signature = joinPoint.getSignature();


        //代理的是哪一个方法
        System.out.println("[-代理执行的方法:"+signature.getName() +"-]");
        //AOP代理类的名字
        System.out.println("[-代理执行的类:"+signature.getDeclaringTypeName() +"-]");
        //AOP代理类的类（class）信息
        System.out.println("[-AOP代理类的类（class）信息:"+ signature.getDeclaringType()+"-]");

        /**
         * 获取RequestAttributes
         * 获得请求的参数
         * 记录请求内容
         *
         * 接收到请求，记录请求内容
         *
         */
        //获取目标方法的参数信息
        Object[] objects = joinPoint.getArgs();
        //获取RequestAttributes
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        //从获取RequestAttributes中获取HttpServletRequest的信息
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
        //也可以获取session内容
        //HttpSession session = (HttpSession) requestAttributes.resolveReference(RequestAttributes.REFERENCE_SESSION);
        System.out.println("URL : " + request.getRequestURL().toString());
        System.out.println("HTTP_METHOD : " + request.getMethod());
        System.out.println("IP : " + request.getRemoteAddr());
        System.out.println("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        //ARGS 是请求参数
        System.out.println("ARGS : " + Arrays.toString(joinPoint.getArgs()));

    }

    /**
     * after1
     * 后置最终通知,final增强，不管是抛出异常或者正常退出都会执行
     */
    @After("executeService()")
    public void deAfter() {
        System.out.println("--aop=after");

        System.out.println("=one]");
    }

    /**
     * after2
     * 在目标方法成功执行后调用通知
     */
    @AfterReturning(returning = "result",pointcut = "executeService()")
    public void doAfterReturing(Object result) throws Throwable {
        /**
         * 处理完请求，返回内容
         */

        System.out.println("返回内容 result = " + result);

    }

    /**
     * 在before 之前，在after之前
     * @param pjp
     * @return
     */
    @Around("executeService()")
    public Object arround(ProceedingJoinPoint pjp) {

        try {

            System.out.println("one方法环绕start.....");
            Object o =  pjp.proceed();
            System.out.println("one方法环绕proceed，结果是 :" + o);
            return o;
        } catch (Throwable e) {
            e.printStackTrace();
            return null;
        }
    }

    //环绕通知,环绕增强，相当于MethodInterceptor
    /**
     * 异常通知
     */
    @AfterThrowing(pointcut = "executeService()")
    public void throwing() {

    }






}
